﻿using DigitalRubyShared;
using UnityEngine;
using XLua;
using Yoozoo.Framework.Managers;

namespace Yoozoo.Modules.Furnitures
{
    public class FingerGesture : MonoBehaviour
    {
        public const string LuaFunctionNameOnPan = "L_TouchManager.OnPan";
        public const string LuaFunctionNameOnTilt = "L_TouchManager.OnTilt";
        public const string LuaFunctionNameOnZoom = "L_TouchManager.OnZoom";
        public const string LuaFunctionNameOnRotate = "L_TouchManager.OnRotate";

        private LuaFunction luaOnPan;
        private LuaFunction luaOnTilt;
        private LuaFunction luaOnZoom;
        private LuaFunction luaOnRotate;
        private LuaEnv luaState;

        public PanGestureRecognizer PanGesture { get; private set; }

        public PanGestureRecognizer TiltGesture { get; private set; }

        public ScaleGestureRecognizer ScaleGesture { get; private set; }

        public RotateGestureRecognizer RotateGesture { get; private set; }

        private void PanGestureCallback(GestureRecognizer gesture)
        {
            if (gesture.State == GestureRecognizerState.Executing)
            {
                panX = DigitalRubyShared.DeviceInfo.PixelsToUnits(gesture.DeltaX) * Time.deltaTime;
                panY = DigitalRubyShared.DeviceInfo.PixelsToUnits(gesture.DeltaY) * Time.deltaTime;
                luaOnPan?.Call(panX, panY);
            }
        }

        private void TiltGestureCallback(GestureRecognizer gesture)
        {
            if (gesture.State == GestureRecognizerState.Executing)
            {
                tilt = DigitalRubyShared.DeviceInfo.PixelsToUnits(gesture.DeltaY) * Time.deltaTime;
                luaOnTilt?.Call(tilt);
            }
        }

        private void ScaleGestureCallback(GestureRecognizer gesture)
        {
            if (gesture.State == GestureRecognizerState.Executing)
            {
                zoom = ScaleGesture.ScaleMultiplierRange * Time.deltaTime;
                luaOnZoom?.Call(zoom);
            }
        }

        private void RotateGestureCallback(GestureRecognizer gesture)
        {
            if (gesture.State == GestureRecognizerState.Executing)
            {
                rotate = RotateGesture.RotationDegreesDelta * Time.deltaTime;
                luaOnRotate?.Call(rotate);
            }
        }

        private void Awake()
        {
            if (!FingersScript.HasInstance)
            {
                gameObject.AddComponent<FingersScript>();
            }

            luaState = LuaManager.mainState;
            luaOnPan = luaState.Global.GetInPath<LuaFunction>(LuaFunctionNameOnPan);
            luaOnTilt = luaState.Global.GetInPath<LuaFunction>(LuaFunctionNameOnTilt);
            luaOnZoom = luaState.Global.GetInPath<LuaFunction>(LuaFunctionNameOnZoom);
            luaOnRotate = luaState.Global.GetInPath<LuaFunction>(LuaFunctionNameOnRotate);
        }

        private void OnEnable()
        {
            PanGesture = new PanGestureRecognizer();
            PanGesture.StateUpdated += PanGestureCallback;
            FingersScript.Instance.AddGesture(PanGesture);

            TiltGesture = new PanGestureRecognizer();
            TiltGesture.StateUpdated += TiltGestureCallback;
            TiltGesture.ThresholdUnits = 0.5f; // higher than normal to not interfere with other gestures
            TiltGesture.MinimumNumberOfTouchesToTrack = TiltGesture.MaximumNumberOfTouchesToTrack = 2;
            FingersScript.Instance.AddGesture(TiltGesture);

            ScaleGesture = new ScaleGestureRecognizer();
            ScaleGesture.StateUpdated += ScaleGestureCallback;
            FingersScript.Instance.AddGesture(ScaleGesture);

            RotateGesture = new RotateGestureRecognizer();
            RotateGesture.StateUpdated += RotateGestureCallback;
            FingersScript.Instance.AddGesture(RotateGesture);

            PanGesture.AllowSimultaneousExecution(ScaleGesture);
            PanGesture.AllowSimultaneousExecution(RotateGesture);
            ScaleGesture.AllowSimultaneousExecution(RotateGesture);
        }

        private void OnDisable()
        {
            if (FingersScript.HasInstance)
            {
                FingersScript.Instance.RemoveGesture(PanGesture);
                FingersScript.Instance.RemoveGesture(ScaleGesture);
                FingersScript.Instance.RemoveGesture(RotateGesture);
            }
        }

        public float PanXScale = 1000;
        public float PanYScale = 1000;
        public float TiltScale = 1000;
        public float ZoomScale = 1000;
        public float RotateScale = 1000;
        
        private float panX;
        private float panY;
        private float tilt;
        private float zoom;
        private float rotate;

        // private void OnGUI()
        // {
        //     var rect = new Rect(50, 600, 400, 50);
        //
        //     GUI.Label(rect, $"pan: ({panX:f2}, {panY:f2}), tilt: {tilt}, zoom: {zoom}, rotate: {rotate}");
        // }

    }
}
